home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / gui / toolbox / imagefx.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  16KB  |  417 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. DISABLE_ALL_CACHING = False
  5. NUM_IMAGES_TO_CACHE = 80
  6. from util import try_this
  7. from util.lrucache import LRU
  8. import wx
  9. from wx import ImageFromDataWithAlpha, BitmapFromImage, Bitmap, BitmapFromIcon, ImageFromBitmap, IMAGE_QUALITY_HIGH, Point
  10. from PIL import Image, ImageDraw, ImageFilter, ImageMath, ImageFont, ImageOps, ImageEnhance
  11. from PIL.Image import BICUBIC, ANTIALIAS
  12. from functools import wraps
  13. from uuid import uuid1
  14. imagecache = LRU(NUM_IMAGES_TO_CACHE)
  15. CORNERS = (('tl', None), ('tr', Image.ROTATE_270), ('bl', Image.FLIP_TOP_BOTTOM), ('br', Image.ROTATE_180))
  16.  
  17. def cacheing(func):
  18.     name = func.__name__
  19.     
  20.     def wrapper(img, *a):
  21.         
  22.         try:
  23.             cachekey = img.cachekey
  24.         except AttributeError:
  25.             
  26.             try:
  27.                 cachekey = (img.path,)
  28.             except AttributeError:
  29.                 img.path = str(uuid1())
  30.                 cachekey = (img.path,)
  31.             except:
  32.                 None<EXCEPTION MATCH>AttributeError
  33.             
  34.  
  35.             None<EXCEPTION MATCH>AttributeError
  36.  
  37.         key = cachekey + (name + repr(a),)
  38.         
  39.         try:
  40.             return imagecache[key]
  41.         except KeyError:
  42.             img = func(img, *a)
  43.             img.cachekey = key
  44.             imagecache[key] = img
  45.             return img
  46.  
  47.  
  48.     wrapper = (None, wraps(func))(wrapper)
  49.     return wrapper
  50.  
  51. if DISABLE_ALL_CACHING:
  52.     import sys
  53.     print >>sys.stderr, 'WARNING: image caching is disabled'
  54.     objmemoize = refmemoize = cacheing = (lambda f: f)
  55. else:
  56.     refmemoize = objmemoize = cacheing
  57.  
  58. def wxbitmap_to_wximage(wxbitmap):
  59.     return wxbitmap.ConvertToImage()
  60.  
  61. wxbitmap_to_wximage = cacheing(wxbitmap_to_wximage)
  62.  
  63. def wxbitmap_to_pil(wxbitmap):
  64.     return wximage_to_pil(wxbitmap_to_wximage(wxbitmap))
  65.  
  66. wxbitmap_to_pil = refmemoize(wxbitmap_to_pil)
  67.  
  68. def wxicon_to_pil(wxicon):
  69.     return wxbitmap_to_pil(BitmapFromIcon(wxicon))
  70.  
  71. wxicon_to_pil = cacheing(wxicon_to_pil)
  72.  
  73. def wxicon_to_bitmap(wxicon):
  74.     return BitmapFromIcon(wxicon)
  75.  
  76. wxicon_to_bitmap = cacheing(wxicon_to_bitmap)
  77.  
  78. def wximage_to_pil(wximage):
  79.     size = (wximage.Width, wximage.Height)
  80.     img = Image.new('RGB', size)
  81.     img.fromstring(wximage.Data)
  82.     (r, g, b) = img.split()
  83.     if wximage.HasAlpha() or wximage.HasMask():
  84.         a = Image.new('L', wximage.GetSize())
  85.         if wximage.HasMask():
  86.             if not wximage.HasAlpha():
  87.                 wximage.InitAlpha()
  88.             
  89.         
  90.         if wximage.HasAlpha():
  91.             a.fromstring(wximage.AlphaData)
  92.         
  93.         img = Image.merge('RGBA', (r, g, b, a))
  94.     else:
  95.         img = Image.merge('RGB', (r, g, b))
  96.     return img
  97.  
  98. wximage_to_pil = refmemoize(wximage_to_pil)
  99.  
  100. def wximage_to_wxbitmap(wximage, depth = 32):
  101.     return BitmapFromImage(wximage)
  102.  
  103.  
  104. def pil_to_wxbitmap(pilimg):
  105.     return wximage_to_wxbitmap(pil_to_wximage(pilimg), 32)
  106.  
  107. pil_to_wxbitmap = objmemoize(pil_to_wxbitmap)
  108.  
  109. def pil_to_wximage(pilimg):
  110.     pilimage = None if pilimg.mode == 'RGBA' else pilimg.convert('RGBA')
  111.     (w, h) = pilimg.size
  112.     rgb = pilimage.tostring('raw', 'RGB')
  113.     alpha = pilimage.tostring('raw', 'A')
  114.     return ImageFromDataWithAlpha(w, h, rgb, alpha)
  115.  
  116. pil_to_wximage = objmemoize(pil_to_wximage)
  117.  
  118. def wxbitmap_inverted(wxbitmap):
  119.     return ImageOps.invert(pilimg_convert(wxbitmap.PIL, 'RGB')).WXB
  120.  
  121. wxbitmap_inverted = cacheing(wxbitmap_inverted)
  122.  
  123. def has_transparency(i):
  124.     return any(i.histogram()[768:1024])
  125.  
  126.  
  127. def pil_to_white_gif(i):
  128.     bg = Image.new('RGBA', i.size, (255, 255, 255, 255))
  129.     bg.paste(i, i)
  130.     return pil_to_gif(bg)
  131.  
  132.  
  133. def pil_to_gif(i):
  134.     (r, g, b, a) = i.split()
  135.     rgb = Image.merge('RGB', (r, g, b))
  136.     rgb = rgb.convert('P', palette = Image.ADAPTIVE, colors = 255, dither = Image.NONE)
  137.     pal = rgb.getpalette()
  138.     r1 = pal[::3]
  139.     g1 = pal[1::3]
  140.     b1 = pal[2::3]
  141.     rv = (set(range(256)) - set(r1)).pop()
  142.     gv = (set(range(256)) - set(g1)).pop()
  143.     bv = (set(range(256)) - set(b1)).pop()
  144.     pal[-3:] = [
  145.         rv,
  146.         gv,
  147.         bv]
  148.     rgb.putpalette(pal, rawmode = 'RGB')
  149.     a2 = a.point((lambda p: None if p >= 128 else 255))
  150.     rgb.paste(255, (0, 0), a2)
  151.     import cStringIO as cStringIO
  152.     s = cStringIO.StringIO()
  153.     rgb.save(s, 'GIF', transparency = 255, interlace = False)
  154.     return s.getvalue()
  155.  
  156.  
  157. def wxbitmap_resizedwh(wxbitmap, w, h):
  158.     return pil_to_wxbitmap(pilimg_resizedwh(wximage_to_pil(wxbitmap_to_wximage(wxbitmap)), w, h))
  159.  
  160. wxbitmap_resizedwh = refmemoize(wxbitmap_resizedwh)
  161.  
  162. def wxbitmap_resized(wxbitmap, size):
  163.     
  164.     try:
  165.         (w, h) = size
  166.     except TypeError:
  167.         return wxbitmap_in_square(wxbitmap, size)
  168.  
  169.     return wxbitmap_resizedwh(wxbitmap, w, h)
  170.  
  171. wxbitmap_resized = refmemoize(wxbitmap_resized)
  172.  
  173. def wxbitmap_resized_smaller(wxbitmap, size):
  174.     if max(wxbitmap.Width, wxbitmap.Height) > size:
  175.         return wxbitmap.Resized(size)
  176.     else:
  177.         return wxbitmap
  178.  
  179.  
  180. def pil_resized_smaller(pil, size):
  181.     return None if max(pil.size) > size else pil
  182.  
  183.  
  184. def pilimg_resized(pilimg, size):
  185.     
  186.     try:
  187.         (w, h) = size
  188.     except TypeError:
  189.         return pilimg_in_square(pilimg, size)
  190.  
  191.     return pilimg_resizedwh(pilimg, w, h)
  192.  
  193. pilimg_resized = objmemoize(pilimg_resized)
  194.  
  195. def pilimg_convert(pilimg, mode):
  196.     return pilimg.convert(mode)
  197.  
  198. pilimg_convert = objmemoize(pilimg_convert)
  199.  
  200. def pilimg_resizedwh(pilimg, w, h):
  201.     w = None if w == -1 else int(w)
  202.     h = None if h == -1 else int(h)
  203.     size = (w, h)
  204.     if pilimg.mode == 'P':
  205.         pilimg = pilimg_convert(pilimg, 'RGBA')
  206.     
  207.     return None(pilimg.resize, size if min(size) < min(pilimg.size) else Image.BICUBIC)
  208.  
  209. pilimg_resizedwh = objmemoize(pilimg_resizedwh)
  210.  
  211. def pilimg_in_square(img, squaresize):
  212.     (w, h) = img.size
  213.     if img.mode == 'P':
  214.         img = pilimg_convert(img, 'RGBA')
  215.     
  216.     new = Image.new('RGBA', (squaresize, squaresize), (0, 0, 0, 0))
  217.     if w > h:
  218.         new_height = int((h / float(w)) * squaresize)
  219.         img = None(img.resize, (squaresize, new_height) if squaresize > w else ANTIALIAS)
  220.         new.paste(img, (0, (squaresize - new_height) / 2))
  221.     else:
  222.         new_width = int((w / float(h)) * squaresize)
  223.         img = None(img.resize, (new_width, squaresize) if squaresize > h else ANTIALIAS)
  224.         new.paste(img, ((squaresize - new_width) / 2, 0))
  225.     return new
  226.  
  227. pilimg_in_square = objmemoize(pilimg_in_square)
  228.  
  229. def pil_resize_canvas(img, w, h, alignment = wx.ALIGN_CENTER):
  230.     if alignment != wx.ALIGN_CENTER:
  231.         raise NotImplemented
  232.     
  233.     (ow, oh) = img.size
  234.     new = Image.new('RGBA', (w, h), (0, 0, 0, 0))
  235.     new.paste(img, (w / 2 - ow / 2, w / 2 - oh / 2))
  236.     return new
  237.  
  238. pil_resize_canvas = objmemoize(pil_resize_canvas)
  239.  
  240. def pil_setalpha(img, alpha):
  241.     channels = img.split()
  242.     if len(channels) == 4:
  243.         (r, g, b, a) = channels
  244.     elif len(channels) == 3:
  245.         a = Image.new('L', img.size, 'white')
  246.     else:
  247.         raise AssertionError('Cannot set alpha, image does not have 3 or 4 bands.')
  248.     img.putalpha(ImageEnhance.Brightness(a).enhance(alpha))
  249.  
  250.  
  251. def wxbitmap_in_square(bmp, squaresize, scaleup = True):
  252.     w = bmp.Width
  253.     h = bmp.Height
  254.     if w > squaresize and h > squaresize or scaleup:
  255.         img = ImageFromBitmap(bmp)
  256.         if w > h:
  257.             new_height = int((h / float(w)) * squaresize)
  258.             img = img.Scale(squaresize, new_height, IMAGE_QUALITY_HIGH)
  259.             offset = Point(0, (squaresize - new_height) / 2)
  260.         else:
  261.             new_width = int((w / float(h)) * squaresize)
  262.             img = img.Scale(new_width, squaresize, IMAGE_QUALITY_HIGH)
  263.             offset = Point((squaresize - new_width) / 2, 0)
  264.         return BitmapFromImage(img)
  265.     
  266.     return bmp
  267.  
  268. wxbitmap_in_square = refmemoize(wxbitmap_in_square)
  269.  
  270. def wxbitmap_greyed(bitmap):
  271.     return wximage_to_wxbitmap(wxbitmap_to_wximage(bitmap).ConvertToGreyscale())
  272.  
  273. wxbitmap_greyed = refmemoize(wxbitmap_greyed)
  274.  
  275. def pilimg_greyed(pil):
  276.     pil = pil.copy()
  277.     alpha = 'A' in pil.getbands()
  278.     if alpha:
  279.         (r, g, b, a) = pil.split()
  280.     
  281.     pil = ImageOps.grayscale(pil)
  282.     if alpha:
  283.         pil.putalpha(a)
  284.     
  285.     return pil
  286.  
  287. pilimg_greyed = objmemoize(pilimg_greyed)
  288.  
  289. def drop_shadow(image, offset = (5, 5), background = (0, 0, 0, 0), shadow = 4473924, border = 8, iterations = 3):
  290.     image = image.PIL
  291.     totalWidth = image.size[0] + abs(offset[0]) + 2 * border
  292.     totalHeight = image.size[1] + abs(offset[1]) + 2 * border
  293.     back = Image.new(image.mode, (totalWidth, totalHeight), background)
  294.     shadowLeft = border + max(offset[0], 0)
  295.     shadowTop = border + max(offset[1], 0)
  296.     back.paste(shadow, [
  297.         shadowLeft,
  298.         shadowTop,
  299.         shadowLeft + image.size[0],
  300.         shadowTop + image.size[1]])
  301.     n = 0
  302.     while n < iterations:
  303.         back = back.filter(ImageFilter.BLUR)
  304.         n += 1
  305.     imageLeft = border - min(offset[0], 0)
  306.     imageTop = border - min(offset[1], 0)
  307.     back.paste(image, (imageLeft, imageTop))
  308.     return back
  309.  
  310.  
  311. def pil_combine(imgs, direction = wx.HORIZONTAL, align = wx.ALIGN_CENTER):
  312.     imgs = [ img.PIL for img in imgs ]
  313.     length_idx = [
  314.         wx.HORIZONTAL,
  315.         wx.VERTICAL].index(direction)
  316.     breadth_idx = [] if length_idx else 1
  317.     for img in imgs:
  318.         size = img.size
  319.         length += size[length_idx]
  320.         breadth = max(breadth, size[breadth_idx])
  321.     
  322.     newsize = length = breadth = 0 if direction == wx.HORIZONTAL else (breadth, length)
  323.     newimg = Image.new('RGBA', newsize, (0, 0, 0, 0))
  324.     pos = (0, 0)
  325.     for img in imgs:
  326.         newimg.paste(img, pos)
  327.         if direction == wx.HORIZONTAL:
  328.             pos = (pos[0] + img.size[0], pos[1])
  329.             continue
  330.         []
  331.         pos = (pos[0], pos[1] + img.size[1])
  332.     
  333.     return newimg
  334.  
  335.  
  336. def rounded_corners(corner_size = 1, rounded_imgs = { }):
  337.     if not isinstance(corner_size, int):
  338.         corner_size = (try_this,)((lambda : int(bool(corner_size))), 1)
  339.     else:
  340.         corner_size = max(0, min(corner_size, 3))
  341.     
  342.     try:
  343.         return rounded_imgs[corner_size]
  344.     except KeyError:
  345.         pass
  346.  
  347.     imgs = []
  348.     skin = skin
  349.     import gui
  350.     rounded_img = Image.open(skin.resourcedir() / ('corner' + str(corner_size) + '.gif')).convert('L')
  351.     for name, rotation in CORNERS:
  352.         mask = None if rotation is not None else rounded_img
  353.         imgs.append(mask)
  354.     
  355.     return rounded_imgs.setdefault(corner_size, imgs)
  356.  
  357.  
  358. def rounded_mask(size, cornersize = 1):
  359.     img = Image.new('L', size, 255)
  360.     (w, h) = size
  361.     p = img.paste
  362.     r = rounded_corners(cornersize)
  363.     i = r[0]
  364.     p(i, (0, 0, i.size[0], i.size[1]))
  365.     i = r[1]
  366.     p(i, (w - i.size[0], 0, w, i.size[1]))
  367.     i = r[2]
  368.     p(i, (0, h - i.size[1], i.size[0], h))
  369.     i = r[3]
  370.     p(i, (w - i.size[0], h - i.size[1], w, h))
  371.     return img
  372.  
  373.  
  374. def pilimg_rounded(image, cornersize = 1):
  375.     newimage = image.copy()
  376.     newimage.putalpha(ImageMath.eval('convert(min(a,b), "L")', a = newimage.split()[-1], b = rounded_mask(newimage.size, cornersize)))
  377.     return newimage
  378.  
  379. pilimg_rounded = objmemoize(pilimg_rounded)
  380.  
  381. def wxbitmap_rounded(wxbitmap, cornersize = 1):
  382.     if cornersize == 0:
  383.         return wxbitmap
  384.     else:
  385.         return pil_to_wxbitmap(pilimg_rounded(wximage_to_pil(wxbitmap_to_wximage(wxbitmap)), cornersize))
  386.  
  387. wxbitmap_rounded = refmemoize(wxbitmap_rounded)
  388. Image.Image.Resized = pilimg_resized
  389. Image.Image.ResizedSmaller = pil_resized_smaller
  390. Image.Image.Rounded = pilimg_rounded
  391. Image.Image.WXB = property((lambda pil: pil_to_wxbitmap(pil)))
  392. Image.Image.WX = property((lambda pil: pil_to_wximage(pil)))
  393. Image.Image.Greyed = property(pilimg_greyed)
  394. Image.Image.ResizeCanvas = pil_resize_canvas
  395. Image.Image.PIL = property((lambda pil: pil))
  396. wx.Bitmap.Resized = wxbitmap_resized
  397. wx.Bitmap.ResizedSmaller = wxbitmap_resized_smaller
  398. wx.Bitmap.Greyed = property(wxbitmap_greyed)
  399. wx.Bitmap.Rounded = wxbitmap_rounded
  400. wx.Bitmap.WXB = property((lambda self: self))
  401. wx.Bitmap.WX = property((lambda wxb: wxbitmap_to_wximage(wxb)))
  402. wx.Bitmap.PIL = property((lambda self: wxbitmap_to_pil(self)))
  403. wx.Bitmap.Inverted = property(wxbitmap_inverted)
  404. wx.Image.WX = property((lambda self: self))
  405. wx.Image.WXB = property((lambda self: wximage_to_wxbitmap(self, 32)))
  406. wx.Image.PIL = property((lambda self: wximage_to_pil(self)))
  407. wx.Icon.PIL = property((lambda self: wxicon_to_pil(self)))
  408. wx.Icon.WXB = property((lambda self: wxicon_to_bitmap(self)))
  409. if __name__ == '__main__':
  410.     from tests.testapp import testapp
  411.     from gui.skin import get
  412.     a = testapp('../../..')
  413.     img = Image.new('RGBA', (40, 50), 'red')
  414.     img.Resized(100).Show()
  415.     a.MainLoop()
  416.  
  417.